package com.journaldev.fusedlocationprovider;

import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

/**
 * Created by zhuoyue on 2017/9/20.
 */

public class GpsLocationManager implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener, LocationListener {

    private static final long UPDATE_INTERVAL = 2000;
    private static final long FASTEST_INTERVAL = 2000;

    private GoogleApiClient mGoogleApiClient;
    private Context context;
    private boolean isReady = false;

    private LocationChangeListener locationChangeListener;

    public GpsLocationManager(Context context) {
        this.context = context.getApplicationContext();
        mGoogleApiClient = new GoogleApiClient.Builder(this.context)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        isReady = true;
    }

    @Override
    public void onConnectionSuspended(int i) {
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.e("mmp", "connect GoogleApiClient failed, reason is：" + connectionResult.getErrorMessage());
        isReady = false;
    }

    @Override
    public void onLocationChanged(Location location) {
        if(location != null) {
            callbackLocation(location);
        }
    }

    /**
     * 开始定位
     */
    public void startLocation() {
        if(!isReady) {
            mGoogleApiClient.connect();
            return;
        }
        if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Log.e("mmp", "location permission is not enable.");
            return;
        }
        Location mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if(mLocation != null) {
            callbackLocation(mLocation);
        }
        startLocationUpdates();
    }

    private void callbackLocation(Location location) {
        if(locationChangeListener != null) {
            locationChangeListener.onLocationChanged(location);
        }
    }

    private void startLocationUpdates() {
        LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        if (ActivityCompat.checkSelfPermission(context,
                android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Log.e("mmp", "location permission is not enable.");
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
    }

    /**
     * 停止更新定位，但是不断开与GoogleApiClient的连接
     * @param disConnect 是否与GoogleApiClient断开连接
     */
    public void stopLocation(boolean disConnect) {
        if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi
                    .removeLocationUpdates(mGoogleApiClient, this);
            if(disConnect) {
                mGoogleApiClient.disconnect();
            }
        }
    }

    /**
     * 检查谷歌服务是否可用
     * @return {true | false}
     */
    public boolean checkPlayServicesEnable() {
        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
        int resultCode = apiAvailability.isGooglePlayServicesAvailable(context);
        return (resultCode == ConnectionResult.SUCCESS);
    }

    public void setLocationChangeListener(LocationChangeListener locationChangeListener) {
        this.locationChangeListener = locationChangeListener;
    }

    public void removeLocationChangeListener() {
        this.locationChangeListener = null;
    }

}
